import axios from "axios";
import router from "../router";
import {Loading} from "element-ui";
import {messages} from "../assets/js/common.js"; // tips file
import store from '../store';

const httpStatus = {
  201: "内容保存成功！",
  202: "您的请求已提交，请耐心等待服务器处理！",
  204: "记录删除成功！",
  400: "发出的请求有错误，服务器没有进行新建或修改数据的操作。",
  401: "用户没有权限（令牌、用户名、密码错误）。",
  403: "用户得到授权，但是访问是被禁止的。",
  404: "Not found",
  406: "请求的格式不可得。",
  410: "请求的资源被永久删除，且不会再得到的。",
  422: "当创建一个对象时，发生一个验证错误。",
  500: "服务器发生错误，请检查服务器。",
  502: "网关错误。",
  503: "服务不可用，服务器暂时过载或维护。",
  504: "网关超时。"
}

// create axios service
const service = axios.create({
    // set request base url
    baseURL: process.env.VUE_APP_LOGOUT_URL,
    
    // set request timeout
    timeout: 5000
});

// loading variable
let loading = null;

// request interceptors
service.interceptors.request.use(
    config => {
        // request bearer token
        if (store.state.token) {
            config.headers.Authorization = `Bearer ${store.state.token}`
        }

        // config login
        config.loading = Loading.service({
            text: "Loding......",
            fullscreen: true
        });
        
        return config;
    },
    error => {
        return Promise.reject(error)
    }
)

// response interceptors
service.interceptors.response.use(
    response => {
        return new Promise((resolve, reject) => {
            // request success close loading
            if (loading) {
                loading.close();
            }

            // response data
            const res = response.data;
            if (res.code === 200) {
                resolve(res)
            } else {
                reject(res)
            }
        });
    },
    error => {
        // request success close loading
        if (loading) {
            loading.close();
        }

        // Broken network or request timeout
        if (!error.response) {
            messages("error", 'request timeout');
            return;
        }

        // authorize be short of
        if (error.response.status === 401) {
            messages("warning", httpStatus[error.response.status]);
            store.state.commit('', '');
            setTimeout(() => {
                router.replace({
                    path: "login",
                    query: {
                        redirect: router.currentRoute.fullPath
                    }
                }, 1000);
            });
        }
        
        // error tips
        messages("error", httpStatus[error.response.status] !== undefined ? httpStatus[error.response.status] : error.response.data.message);
        
        return Promise.reject(error)
    }
)

// get request
// @params {string} url
// @params {Object} params
export function get(url, params) {
    return new Promise((resolve, reject) => {
        service.get(url, {params}).then(res => {
            resolve(res);
        }).catch(err => {
            reject(err);
        });
    })
}

// post request
// @params {string} url
// @params {Object} params
export function post(url, params) {
    return new Promise((resolve, reject) => {
        service.post(url, params).then(res => {
            resolve(res);
        }).catch(err => {
            reject(err);
        });
    });
}

// put request
// @params {string} url
// @params {Object} params
export function put(url, params) {
    return new Promise((resolve, reject) => {
        service.put(url, params).then(res => {
            resolve(res);
        }).catch(err => {
            reject(err);
        });
    });
}

// patch request
// @params {string} url
// @params {Object} params
export function patch(url, params) {
    return new Promise((resolve, reject) => {
        service.patch(url, params).then(res => {
            resolve(res);
        }).catch(err => {
            reject(err);
        });
    });
}

// delete request
// @params {string} url
// @params {Object} params
export function del(url, params) {
    return new Promise((resolve, reject) => {
        service.delete(url, {params}).then(res => {
            resolve(res);
        }).catch(err => {
            reject(err);
        })
    });
}